package model.entity;

import java.util.Date;

import model.entity.container.ProductContainer;

import common.Barcode;
import common.Result;

/**
 * Represents each purchased item that exists in inventory.
 * 
 * @author Trevor Dixon, Ian Ryu
 * 
 */
public class Item extends Entity
{
  private static final long serialVersionUID = -5336380052149876111L;

  private final Product     product;
  private final Barcode     barcode;
  private final Date        entryDate;
  private Date              exitTime;
  private Date              expirationDate;
  private ProductContainer  container;

  public Item(Product product, Barcode barcode, Date entryDate, Date expirationDate,
      ProductContainer container)
  {
    this.product = product;
    this.barcode = barcode;
    this.entryDate = entryDate;
    this.expirationDate = expirationDate;
    this.container = container;
  }

  public Barcode getBarcode()
  {
    return barcode;
  }

  public Date getEntryDate()
  {
    return entryDate;
  }

  public Date getExitTime()
  {
    return exitTime;
  }

  public Result setExitTime(Date exitTime)
  {
    Result validExitTime = validateExitTime(exitTime);

    if (!validExitTime.getStatus())
    {
      return validExitTime;
    }

    this.exitTime = exitTime;
    return new Result(true);
  }

  public Result validateExitTime(Date exitTime)
  {

    if (exitTime == null)
    {
      return new Result(false, "Exit Time is Null/wrong foramtted");
    }

    return new Result(true);
  }

  public Date getExpirationDate()
  {
    return expirationDate;
  }

  public Result setExpirationDate(Date expirationDate)
  {
    Result validExpirationDate = validateExpirationDate(expirationDate);

    if (!validExpirationDate.getStatus())
    {
      return validExpirationDate;
    }

    this.expirationDate = expirationDate;
    return new Result(true);
  }

  public Result validateExpirationDate(Date expirationDate)
  {

    if (expirationDate == null)
    {
      return new Result(false, "Expiration Date is Null/wrong foramtted");
    }

    return new Result(true);
  }

  /**
   * @param productContainer
   * 
   * @return A result indicating whether the operation was successful.
   */
  public Result validateAddToProductContainer(ProductContainer container)
  {
    if (container == null)
    {
      return new Result(false, "Error: Null Item.");
    }

    return new Result(true);
  }

  /**
   * @param productContainer
   * 
   * @return A result indicating whether the operation was successful.
   */
  public Result addToProductContainer(ProductContainer container)
  {
    Result validAdd = validateAddToProductContainer(container);
    if (!validAdd.getStatus())
    {
      return validAdd;
    }

    this.container = container;
    return new Result(true);
  }

  /**
   * @param productContainer
   * 
   * @return A result indicating whether the operation was successful.
   */
  public Result validateRemoveFromProductContainer(ProductContainer container)
  {
    if (container == null)
    {
      return new Result(false, "Error: Null Item.");
    }

    return new Result(true);
  }

  /**
   * @param productContainer
   * 
   * @return A result indicating whether the operation was successful.
   */
  public Result removeFromProductContainer(ProductContainer container)
  {
    Result validRemove = validateRemoveFromProductContainer(container);
    if (!validRemove.getStatus())
    {
      return validRemove;
    }

    this.container = container;
    return new Result(true);
  }

  public Result validateItem()
  {
    Result validExitTime = validateExitTime(exitTime);
    Result validExpirationDate = validateExpirationDate(expirationDate);
    if (!validExitTime.getStatus() || !validExpirationDate.getStatus())
    {
      return new Result(false, "Invalid item");
    }
    return new Result(true);
  }

  @Override
  public boolean equals(Object obj)
  {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    Item other = (Item) obj;
    if (barcode == null)
    {
      if (other.barcode != null)
        return false;
    }
    else if (!barcode.equals(other.barcode))
      return false;
    return true;
  }

  @Override
  public String toString()
  {
    return "Item [barcode=" + barcode + ", entryDate=" + entryDate + ", exitTime=" + exitTime
        + ", expirationDate=" + expirationDate + ", product=" + product + ", container="
        + container + "]";
  }

}
